#include <iostream>
#include <boost/foreach.hpp>

#include "main.h"

using namespace std;

//------------------------------------------------------------------------------------------------------------
/*
void showStandardSudokuAvailables(StandardSudoku* stSud, map<int,int>* sudBoard)
{
    cout << "showStandardSudokuAvailables ENTER\n";
    set<int> resultSet;
    BOOST_FOREACH(int idx, *(stSud->getPossibleIndices()))
    {
        resultSet.clear();
        stSud->getAvailableSet(idx, &resultSet, sudBoard);
        cout << idx << ": ";
        BOOST_FOREACH(int i, resultSet)
        {
            cout << i << " ";
        }
        cout << endl;
    }
    cout << "showStandardSudokuAvailables EXIT\n";
}
*/
//------------------------------------------------------------------------------------------------------------
/*
void showStandardSudoku(StandardSudoku* stsud)
{
	std::map<int,std::vector<Group*> > grmapIt;
	std::vector<Group*> grIt;
	std::set<int> setIt;
	std::vector<int> vecIt;
	int i;

	//show possible indices
	cout << "Possible indices:\n";
	BOOST_FOREACH(i, *(stsud->getPossibleIndices()))
	{
		cout << i << " ";
	}
	//show possible values
	cout << "\nPossible values:\n";
	BOOST_FOREACH(i, *(stsud->getGeneralPossibleValues()))
	{
		cout << i << " ";
	}
	//show groups
	cout << "\nGroups:\n";
	BOOST_FOREACH(Group* gr, stsud->getGroups())
	{
		BOOST_FOREACH(i, (*gr->getIndicesVector()))
		{
			cout << i << " ";
		}
		cout << "\n";
	}
	//show map groups
	cout << "\nMap of groups:\n";
	BOOST_FOREACH(int i, *(stsud->getPossibleIndices()))
	{
	    cout << "----- Groups for index " << i << " -----------\n";
	    //map<int,vector<Group*>*>* gfi =
	    vector<Group*>* vog = (*(stsud->getGroupsForFieldIdx()))[i];
        BOOST_FOREACH(Group* gp, *vog)
        {
            BOOST_FOREACH(int i, *(gp->getIndicesVector()))
            {
                cout << i << " ";
            }
            cout << endl;
        }
        cout << endl;
	}
}
*/
//------------------------------------------------------------------------------------------------------------
int main (int argc, char ** argv) {
    /*
    if(argc < 3 || argc > 3) {
        std::cout << "exatcly two parameters required: main <relations_file.in> <initial_file.in>" << std::endl;
        return -1;
    }

    SudokuRelations sudRel(*(argv + 1), NULL);
    */





    std::map<int,int> sudokuBoard;
    std::map<int,int>::iterator sbit;
    std::map<int,std::set<int>* >* availables;

    std::map<int,std::set<int>*>::iterator mip;
    std::set<int>::iterator vit;

    int i;
    //fill zeros
    for(i = 1; i <= 81; i++)
        sudokuBoard[i] = 0;

/*
    sudokuBoard[1] = 2;
    sudokuBoard[4] = 6;
    sudokuBoard[6] = 7;
    sudokuBoard[7] = 5;
    sudokuBoard[17] = 9;
    sudokuBoard[18] = 6;
    sudokuBoard[19] = 6;
    sudokuBoard[21] = 7;
    sudokuBoard[24] = 1;
    sudokuBoard[25] = 3;
    sudokuBoard[29] = 5;
    sudokuBoard[31] = 7;
    sudokuBoard[32] = 3;
    sudokuBoard[33] = 2;
    sudokuBoard[38] = 7;
    sudokuBoard[44] = 2;
    sudokuBoard[49] = 1;
    sudokuBoard[50] = 8;
    sudokuBoard[51] = 9;
    sudokuBoard[53] = 7;
*/
    sudokuBoard[57] = 3;
/*
    sudokuBoard[58] = 5;
    sudokuBoard[61] = 6;
    sudokuBoard[63] = 4;
    sudokuBoard[64] = 8;
    sudokuBoard[65] = 4;
    sudokuBoard[75] = 5;
    sudokuBoard[76] = 2;
    sudokuBoard[78] = 6;
    sudokuBoard[81] = 8;
*/

    //SudokuDefinition* sudokuDef = new StandardSudoku();
    SudokuDefinition* sudokuDef = new SudokuFromFile("standard_sudoku.def");

    SudokuSolvingAlgorithm* salgo = new SudokuSolvingRecursive();
    //SudokuBoard sudBoard(salgo, sudokuDef, &sudokuBoard);
    SudokuBoard sudBoard(salgo, sudokuDef, (char*)"standard_sudoku.ini");

	for(int y = 0; y < 10; y++)
	{
		//go!
		cout << "START!\n";
		//sudBoard.print();

		sudBoard.startSolving(1);

		//printing solutions
		cout << "THERE ARE SOLUTIONS:\n";

		//map<int,int>* solution;

		BOOST_FOREACH(int_int_map* m, *(sudBoard.getSolutions()))
		{
		    i = 1;
		    cout << "---------------------------------------------------\n";
		    BOOST_FOREACH(int_int_pair p, *m)
		    {
		        //cout << "f[" << p.first << "]=" << p.second;
		        cout << "["<<p.first<<"]"<<p.second << " ";
		        if(i % 3 == 0)
		            cout << " ";
		        if(i % 9 == 0)
		            cout << endl;
		        if(i % 27 == 0)
		            cout << endl;
		        i++;
		    }
		    //cout << endl;
		}
		cout << "---------------------------------------------------\nALGORITHM LAPS: " << sudBoard.laps << endl;
    }

    //SudokuRelations sudRel(&sudokuDef);
    //availables = sudRel.getMapAvailables(&sudokuBoard);

    //std::cout << "availables.size=" << availables->size() << std::endl;
    //showStandardSudoku(&sudokuDef);
    //showStandardSudokuAvailables(&sudokuDef, &sudokuBoard);

/*
    for(i = 1; i <= 81; i++)
    {
        std::cout << i << ": ";
        for(vit = (*availables)[i]->begin(); vit != (*availables)[i]->end(); vit++)
        {
            std::cout << *vit << " ";
        }
        std::cout << std::endl;
    }
*/
	return 0;
}
//------------------------------------------------------------------------------------------------------------
